package ru.tennisworld.match.utils.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestTemplate;
import ru.tennisworld.match.dto.integration.UserReferenceDto;
import ru.tennisworld.match.dto.integration.UserUpdateRatingRequestDto;
import ru.tennisworld.match.exceptions.MatchServiceException;
import ru.tennisworld.match.utils.IntegrationClient;
import ru.tennisworld.match.utils.IntegrationClientUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component("integrationClient")
public class IntegrationClientImpl implements IntegrationClient {

    private static final Logger LOG = LoggerFactory.getLogger(IntegrationClient.class);

    @Value("${user-service.url}")
    private String userServiceUrl;

    @Value("${user-service.path.reference-list}")
    private String referenceUserListPath;

    @Value("${user-service.path.update-rating}")
    private String updateUserRatingPath;

    private final RestTemplate restTemplate = new RestTemplate();

    @Override
    public List<UserReferenceDto> getUserReferenceList(List<String> usernameList) {
        LOG.info("operation=IntegrationClientImpl.getUserReferenceList, action=start, params={}", usernameList);
        final Map<String, String> requestMap = new HashMap<>();
        requestMap.put("usernameList", String.join(",", usernameList));
        try {
            final String url = userServiceUrl + referenceUserListPath + "?usernameList={usernameList}";
            ResponseEntity<List<UserReferenceDto>> response =
                    restTemplate.exchange(url, HttpMethod.GET, null, IntegrationClientUtils.USER_REFERENCE_INFO, requestMap);
            List<UserReferenceDto> result = response.getBody();
            LOG.info("operation=IntegrationClientImpl.getUserReferenceList, action=end, result={}", result);
            return result;
        } catch (HttpServerErrorException exception) {
            LOG.error("operation=IntegrationClientImpl.getUserReferenceList, action=error, exception={}", exception.getMessage());
            throw new MatchServiceException("Ошибка получения данных из сервиса пользователей", exception);
        }
    }

    @Override
    public void updateUserRatingAfterMatch(UserUpdateRatingRequestDto request) {
        LOG.info("operation=IntegrationClientImpl.updateUserRatingAfterMatch, action=start, request={}", request);
        try {
            final String url = userServiceUrl + updateUserRatingPath;
            restTemplate.exchange(url, HttpMethod.PUT, new HttpEntity<>(request), Void.class);
            LOG.info("operation=IntegrationClientImpl.updateUserRatingAfterMatch, action=end, request={}", request);
        } catch (HttpServerErrorException exception) {
            LOG.error("operation=IntegrationClientImpl.updateUserRatingAfterMatch, action=error, exception={}", exception.getMessage());
            throw new MatchServiceException("Ошибка обновления рейтинга пользователей", exception);
        }
    }
}
